package de.unibi.comet.tools;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;

import de.unibi.comet.util.Log;
import de.unibi.comet.ac.AhoCorasickAutomaton;
import de.unibi.comet.ac.CharacterDistribution;
import de.unibi.comet.ac.StringSetProvider;
import de.unibi.comet.hmm.ArrayStateAndMassDistribution;
import de.unibi.comet.hmm.HMM;
import de.unibi.comet.hmm.StateAndMassDistribution;

public class aca_stat {

	public static void usage() {
		System.out.println("usage: aca_stat <patterns> <alphabet>");
		System.out.println("   <patterns> file containing patterns");
		System.out.println("   <alphabet> file containing distribution over alphabet");
		System.exit(1);
	}

	public static void main(String[] args) {
		if (args.length!=1) usage();
		FileInputStream patternFile = null;
		try {
			patternFile = new FileInputStream(args[0]);
		} catch (FileNotFoundException e) {
			System.out.println("File not found, sorry!");
			System.exit(1);
		}
		BufferedReader br = new BufferedReader(new InputStreamReader(patternFile));
		ArrayList<String> l = new ArrayList<String>();
		try {
			while (true) {
				String line = br.readLine();
				if (line==null) break;
				l.add(line);
//				System.out.printf("line: %s\n",line);
			}
		} catch (IOException e) {
			System.out.println("I/O failure, sorry!");
			System.exit(1);
		}

		Log.getInstance().setTimingActive(true);
		Log.getInstance().setLogLevel(Log.Level.INSANE);
		//Log.getInstance().setLogLevel(Log.Level.EVERYTHING);
		
		CharacterDistribution charDist = new CharacterDistribution();
//		charDist.set('e', 60.0);
//		charDist.set('h', 5.0);
//		charDist.set('i', 20.0);
//		charDist.set('s', 2.0);
//		charDist.set('r', 3.0);
//		charDist.set('y', 10.0);

		charDist.set('a', 0.1);
		charDist.set('b', 0.2);
		charDist.set('c', 0.3);
		charDist.set('d', 0.4);		

//		charDist.set('a', 0.1);
//		charDist.set('c', 0.2);
//		charDist.set('g', 0.3);
//		charDist.set('t', 0.4);		

//		charDist.set('a', 0.4);
//		charDist.set('b', 0.6);
		charDist.normalize();
		
		StringSetProvider ssp = new StringSetProvider(l);

		AhoCorasickAutomaton aca = new AhoCorasickAutomaton();
		aca.build(ssp);
		System.out.println(aca.pstricksOutput());		
		HMM hmm = aca.createHMM(charDist);
		System.out.println(hmm.toString());	
		StateAndMassDistribution dist = new ArrayStateAndMassDistribution(hmm.getStateCount(),0,false);
		dist.set(0, 0, 1.0);
		
		for (int i=1; i<=10; ++i) {
			dist = hmm.step(dist);
			StringBuffer sb = new StringBuffer();
			sb.append(String.format("i=%d\n", i));
			double sum = 0.0;
			for (int state=0; state<dist.getStateCount(); ++state) {
				double p = dist.getStateProbability(state);
				sb.append(String.format("%3d | %8f | ", state, p));
				sum+=p;
				for (int mass=0; mass<=dist.getMaxMass(); ++mass) {
					sb.append(String.format("%8f ", dist.get(state, mass)));
				}
				sb.append("\n");
			}
			sb.append(String.format(" S  | %8f | ", sum));
			for (int mass=0; mass<=dist.getMaxMass(); ++mass) {
				sb.append(String.format("%8f ", dist.getMassProbability(mass)));
			}
			sb.append("\n");

			sb.append("\n");
			System.out.print(sb.toString());
		}
	}
}
